# -*- coding: utf-8 -*-
"""
用户控制层

负责处理用户相关的HTTP请求和响应
"""
import random
from fastapi import APIRouter, HTTPException, Request, Depends, logger
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from pydantic import BaseModel, Field
from typing import Optional, Dict, Any
import httpx
import hashlib
import base64
import urllib.parse
import json
from app.services.user_service import UserService
from fastapi.encoders import jsonable_encoder
from app.utils.simple_jwt import create_access_token, create_refresh_token
from app.utils.response_util import success_response, error_response
from app.utils.jwt_utils import get_user_id_from_token, JWTError
import logging

logger = logging.getLogger(__name__)

router = APIRouter(
    prefix="/user",
    tags=["user"],
    responses={404: {"description": "Not found"}}
)

# HTTP Bearer token scheme
security = HTTPBearer()

# 初始化服务层
user_service = UserService()

# Pydantic 模型
class WechatLoginRequest(BaseModel):
    code: str = Field(..., description="微信小程序授权码")
    encrypted_data: Optional[str] = Field(None, description="加密的用户数据")
    iv: Optional[str] = Field(None, description="加密算法的初始向量")
    # 添加前端可能发送的其他字段
    avatar: Optional[str] = Field(None, description="用户头像")
    city: Optional[str] = Field(None, description="城市")
    country: Optional[str] = Field(None, description="国家")
    gender: Optional[int] = Field(None, description="性别")
    language: Optional[str] = Field(None, description="语言")
    nickname: Optional[str] = Field(None, description="昵称")
    province: Optional[str] = Field(None, description="省份")
    userInfo: Optional[dict] = Field(None, description="用户信息对象")

class RefreshTokenRequest(BaseModel):
    refresh_token: str = Field(..., description="刷新令牌")


class SmsVerifyRequest(BaseModel):
    appkey: str = Field(..., description="应用的appkey")
    phone: str = Field(..., description="电话号码（不带区号）")
    zone: str = Field(..., description="区号（纯数字）")
    code: str = Field(..., description="需要验证的验证码")


class KdniaoLogisticsRequest(BaseModel):
    shipper_code: str = Field(..., description="快递公司编码")
    logistic_code: str = Field(..., description="快递单号")
    order_code: Optional[str] = Field("", description="订单编号")
    customer_name: Optional[str] = Field("", description="收件人或寄件人手机号后四位")


class KdniaoCallbackRequest(BaseModel):
    RequestData: str = Field(..., description="业务数据")
    EBusinessID: str = Field(..., description="用户ID")
    RequestType: str = Field(..., description="请求类型")
    DataSign: str = Field(..., description="数据签名")
    DataType: str = Field(..., description="数据类型")


class SendSmsCodeRequest(BaseModel):
    phone: str = Field(..., description="手机号码")
    zone: str = Field(default="86", description="区号（默认86）")


class PhoneLoginRequest(BaseModel):
    phone: str = Field(..., description="手机号码")
    code: str = Field(..., description="验证码")
    zone: str = Field(default="86", description="区号（默认86）")


@router.post("/wechat-login")
async def wechat_login(request: WechatLoginRequest, req: Request):
    """微信小程序登录"""
    try:
        # 获取客户端IP
        client_ip = req.client.host if req.client else "unknown"
        
        # 使用code字段作为js_code
        js_code = request.code
        
        # 从userInfo中提取用户信息，如果没有则使用单独字段
        user_info = {}
        if request.userInfo:
            user_info = request.userInfo
        else:
            # 使用单独字段构建用户信息
            user_info = {
                'nickName': request.nickname or '微信用户',
                'avatarUrl': request.avatar or '',
                'gender': request.gender or 0,
                'city': request.city or '',
                'province': request.province or '',
                'country': request.country or '',
                'language': request.language or ''
            }
        
        result = user_service.wechat_login(
            js_code=js_code,
            encrypted_data=request.encrypted_data,
            iv=request.iv,
            client_ip=client_ip,
            user_info=user_info  # 传递用户信息
        )
        return result
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"登录失败: {str(e)}")


@router.post("/logout")
async def logout(credentials: HTTPAuthorizationCredentials = Depends(security)):
    """用户登出"""
    try:
        access_token = credentials.credentials
        success = user_service.logout(access_token)
        
        if success:
            return {
                "code": 200,
                "message": "登出成功"
            }
        else:
            return {
                "code": 400,
                "message": "登出失败，无效的令牌"
            }
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"登出失败: {str(e)}")


@router.post("/refresh-token")
async def refresh_token(request: RefreshTokenRequest):
    """刷新访问令牌"""
    try:
        result = user_service.refresh_token(request.refresh_token)
        
        if result:
            return {
                "code": 200,
                "message": "令牌刷新成功",
                "data": result
            }
        else:
            raise HTTPException(status_code=401, detail="无效的刷新令牌")
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"令牌刷新失败: {str(e)}")


@router.get("/profile")
async def get_user_profile(credentials: HTTPAuthorizationCredentials = Depends(security)):
    """获取用户资料"""
    try:
        access_token = credentials.credentials
        user = user_service.verify_token(access_token)
        
        if not user:
            raise HTTPException(status_code=401, detail="无效的访问令牌")
        
        return {
            "code": 200,
            "message": "获取成功",
            "data": {
                "user_id": user.get('user_id'),
                "user_no": user.get('user_no'),
                "nickname": user.get('nickname'),
                "avatar": user.get('avatar'),
                "phone": user.get('phone'),
                "email": user.get('email'),
                "wechat_nickname": user.get('wechat_nickname'),
                "wechat_avatar": user.get('wechat_avatar'),
                "gender": user.get('gender'),
                "birthday": user.get('birthday'),
                "last_login_time": user.get('last_login_time'),
                "created_time": user.get('created_time')
            }
        }
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取用户资料失败: {str(e)}")


@router.get("/verify-token")
async def verify_token(credentials: HTTPAuthorizationCredentials = Depends(security)):
    """验证访问令牌"""
    try:
        access_token = credentials.credentials
        user = user_service.verify_token(access_token)
        
        if user:
            return {
                "code": 200,
                "message": "令牌有效",
                "data": {
                    "valid": True,
                    "user_id": user.get('user_id')
                }
            }
        else:
            return {
                "code": 401,
                "message": "令牌无效",
                "data": {
                    "valid": False
                }
            }
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"令牌验证失败: {str(e)}")


def get_current_user(request: Request) -> Optional[Dict[str, Any]]:
    """获取当前用户"""
    try:
        # 从请求头获取token
        auth_header = request.headers.get('Authorization')
        if not auth_header or not auth_header.startswith('Bearer '):
            return None
        
        token = auth_header.split(' ')[1]
        user_id = get_user_id_from_token(token)
        
        if not user_id:
            return None
        
        # 获取用户信息
        user = user_service.get_user_info(user_id)
        if user.get('code') == 200:
            return user.get('data')
        
        return None
        
    except JWTError:
        return None
    except Exception as e:
        logger.error(f"获取当前用户失败: {str(e)}")
        return None


@router.post("/debug-wechat-login")
async def debug_wechat_login(request: Request):
    """调试微信登录接口 - 打印请求数据"""
    try:
        # 获取请求体
        body = await request.json()
        
        print("=== 微信登录调试信息 ===")
        print(f"请求体: {body}")
        print(f"Content-Type: {request.headers.get('content-type')}")
        print(f"User-Agent: {request.headers.get('user-agent')}")
        print("========================")
        
        return {
            "code": 200,
            "message": "调试信息已记录",
            "data": {
                "received_data": body,
                "headers": dict(request.headers)
            }
        }
    except Exception as e:
        return {
            "code": 500,
            "message": f"调试失败: {str(e)}",
            "data": None
        }


@router.get("/test-login")
async def test_login():
    """测试登录接口（开发环境使用）"""
    try:
        # 使用固定的测试js_code
        test_js_code = "test_js_code_123456"
        
        result = user_service.wechat_login(
            js_code=test_js_code,
            client_ip="127.0.0.1",
            user_info={
                'nickName': '测试用户',
                'avatarUrl': '',
                'gender': 0
            }
        )
        return result
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"测试登录失败: {str(e)}")


@router.post("/verify-sms")
async def verify_sms(phone: str):
    """验证短信验证码"""
    try:
        random_code = str(random.randint(100000, 999999))
        # 准备请求参数
        payload = {
            "appkey": "246508f55661c",
            "phone": phone,
            "zone": "86",
            "code": random_code
        }
        print(payload)
        # 发送验证请求到第三方API
        async with httpx.AsyncClient() as client:
            response = await client.post(
                "https://webapi.sms.mob.com/sms/verify",
                data=payload,
                timeout=30.0
            )
            print(response.json())
            # 检查HTTP状态码
            if response.status_code != 200:
                raise HTTPException(
                    status_code=response.status_code,
                    detail=f"短信验证服务请求失败: {response.status_code}"
                )
            
            # 解析响应
            result = response.json()
            
            # 根据第三方API的响应格式处理结果
            if result.get("status") == 200:
                return {
                    "code": 200,
                    "message": "短信验证成功",
                    "data": {
                        "verified": True,
                        "phone": phone,
                        "zone": "86"
                    }
                }
            else:
                return {
                    "code": 400,
                    "message": f"短信验证失败: {result.get('error', '未知错误')}",
                    "data": {
                        "verified": False,
                        "error_code": result.get("status"),
                        "error_msg": result.get("error")
                    }
                }
                
    except httpx.TimeoutException:
        raise HTTPException(status_code=408, detail="短信验证请求超时")
    except httpx.RequestError as e:
        raise HTTPException(status_code=500, detail=f"短信验证请求失败: {str(e)}")
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"短信验证失败: {str(e)}")


@router.post("/kdniao-logistics")
async def query_kdniao_logistics(request: KdniaoLogisticsRequest):
    """快递鸟物流查询接口"""
    try:
        # 快递鸟配置（建议从环境变量或配置文件中读取）
        KDNIAO_BASE_URL = "https://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx"
        EBUSINESS_ID = "1889345"  # 替换为您的用户ID
        API_KEY = "65c9cc9a-1d3a-40f7-b7fd-4c337ef0f735"  # 替换为您的API Key
        
        # 构建业务参数
        request_data = {
            "OrderCode": request.order_code,
            "ShipperCode": request.shipper_code,
            "LogisticCode": request.logistic_code,
            "CustomerName": request.customer_name
        }
        
        # 转换为JSON字符串（不压缩格式，用于签名）
        request_data_json = json.dumps(request_data, separators=(',', ':'), ensure_ascii=False)
        
        # 生成签名
        data_sign = generate_kdniao_sign(request_data_json, API_KEY)
        
        # 构建请求参数
        payload = {
            "RequestData": request_data_json,
            "EBusinessID": EBUSINESS_ID,
            "RequestType": "1002",  # 物流轨迹查询
            "DataSign": data_sign,
            "DataType": "2"
        }
        
        print("快递鸟请求参数:", payload)
        
        # 发送请求
        async with httpx.AsyncClient() as client:
            response = await client.post(
                KDNIAO_BASE_URL,
                data=payload,
                headers={"Content-Type": "application/x-www-form-urlencoded;charset=utf-8"},
                timeout=30.0
            )
            
            print("快递鸟响应:", response.text)
            
            if response.status_code != 200:
                raise HTTPException(
                    status_code=response.status_code,
                    detail=f"快递鸟API请求失败: {response.status_code}"
                )
            
            # 解析响应
            result = response.json()
            
            # 检查业务结果
            if result.get("Success"):
                return {
                    "code": 200,
                    "message": "物流查询成功",
                    "data": {
                        "success": True,
                        "shipper_code": result.get("ShipperCode"),
                        "logistic_code": result.get("LogisticCode"),
                        "state": result.get("State"),
                        "state_ex": result.get("StateEx"),
                        "traces": result.get("Traces", [])
                    }
                }
            else:
                return {
                    "code": 400,
                    "message": f"物流查询失败: {result.get('Reason', '未知错误')}",
                    "data": {
                        "success": False,
                        "reason": result.get("Reason")
                    }
                }
                
    except httpx.TimeoutException:
        raise HTTPException(status_code=408, detail="快递鸟API请求超时")
    except httpx.RequestError as e:
        raise HTTPException(status_code=500, detail=f"快递鸟API请求失败: {str(e)}")
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"物流查询失败: {str(e)}")


@router.post("/kdniao_callback")
async def kdniao_callback(request: Request):
    """快递鸟物流轨迹推送回调接口"""
    try:
        # 获取表单数据
        form_data = await request.form()
        
        # 提取回调参数
        request_data = form_data.get("RequestData", "")
        ebusiness_id = form_data.get("EBusinessID", "")
        request_type = form_data.get("RequestType", "")
        data_sign = form_data.get("DataSign", "")
        data_type = form_data.get("DataType", "")
        
        print("快递鸟回调数据:")
        print(f"RequestData: {request_data}")
        print(f"EBusinessID: {ebusiness_id}")
        print(f"RequestType: {request_type}")
        print(f"DataSign: {data_sign}")
        print(f"DataType: {data_type}")
        
        # 验证EBusinessID是否匹配
        if ebusiness_id != "1889345":
            print(f"EBusinessID不匹配: 期望1889345, 实际{ebusiness_id}")
            return {
                "EBusinessID": ebusiness_id,
                "UpdateTime": "2024-11-11T09:52:38.431+00:00",
                "Success": False,
                "Reason": "EBusinessID不匹配"
            }
        
        # 可选：验证签名（如果需要安全校验）
        # api_key = "65c9cc9a-1d3a-40f7-b7fd-4c337ef0f735"
        # expected_sign = generate_kdniao_sign(request_data, api_key)
        # if data_sign != expected_sign:
        #     print("签名验证失败")
        #     return {
        #         "EBusinessID": ebusiness_id,
        #         "UpdateTime": "2024-11-11T09:52:38.431+00:00",
        #         "Success": False,
        #         "Reason": "签名验证失败"
        #     }
        
        # 解析物流数据
        if request_data:
            try:
                logistics_data = json.loads(request_data)
                print("解析的物流数据:", logistics_data)
                
                # 提取关键信息
                success = logistics_data.get("Success", False)
                reason = logistics_data.get("Reason", "")
                shipper_code = logistics_data.get("ShipperCode", "")
                logistic_code = logistics_data.get("LogisticCode", "")
                state = logistics_data.get("State", "")
                traces = logistics_data.get("Traces", [])
                
                print(f"物流状态: Success={success}, State={state}")
                print(f"快递公司: {shipper_code}, 运单号: {logistic_code}")
                print(f"轨迹数量: {len(traces)}")
                
                # 这里可以根据业务需求处理物流数据
                # 例如：更新订单状态、通知用户、存储到数据库等
                # await process_logistics_update(logistics_data)
                
            except json.JSONDecodeError as e:
                print(f"JSON解析失败: {e}")
                return {
                    "EBusinessID": ebusiness_id,
                    "UpdateTime": "2024-11-11T09:52:38.431+00:00",
                    "Success": False,
                    "Reason": "数据格式错误"
                }
        
        # 返回标准格式的成功响应
        return {
            "EBusinessID": ebusiness_id,
            "UpdateTime": "2024-11-11T09:52:38.431+00:00",
            "Success": True,
            "Reason": "接收成功"
        }
        
    except Exception as e:
        print(f"回调处理异常: {e}")
        return {
            "EBusinessID": "1889345",
            "UpdateTime": "2024-11-11T09:52:38.431+00:00",
            "Success": False,
            "Reason": f"处理异常: {str(e)}"
        }


def generate_kdniao_sign(request_data: str, api_key: str) -> str:
    """生成快递鸟数据签名"""
    try:
        # 第一步：RequestData + ApiKey
        sign_str = request_data + api_key
        
        # 第二步：MD5加密（32位小写）
        md5_hash = hashlib.md5(sign_str.encode('utf-8')).hexdigest().lower()
        
        # 第三步：Base64编码
        base64_encoded = base64.b64encode(md5_hash.encode('utf-8')).decode('utf-8')
        
        # 第四步：URL编码
        url_encoded = urllib.parse.quote(base64_encoded, safe='')
        
        return url_encoded
        
    except Exception as e:
        raise Exception(f"签名生成失败: {str(e)}")


@router.post("/sendSmsCode")
async def send_sms_code(request: Request, data: Dict[str, Any]):
    """发送短信验证码"""
    try:
        phone = data.get('phone')
        zone = data.get('zone', '86')
        
        if not phone:
            return error_response("手机号不能为空")
        
        # 这里应该调用短信服务
        # 暂时返回成功
        logger.info(f"发送验证码请求参数: {data}")
        
        return success_response({
            'code': '123456',  # 模拟验证码
            'phone': phone,
            'zone': zone
        }, "验证码发送成功")
        
    except Exception as e:
        logger.error(f"发送验证码失败: {str(e)}")
        return error_response(f"发送验证码失败: {str(e)}")


@router.post("/phone-login")
async def phone_login(request: Request, data: Dict[str, Any]):
    """手机号登录"""
    try:
        phone = data.get('phone')
        code = data.get('code')
        zone = data.get('zone', '86')
        
        # 获取客户端IP
        client_ip = request.client.host if request.client else None
        
        if not phone or not code:
            return error_response("手机号和验证码不能为空")
        
        result = user_service.phone_login(phone, code, zone, client_ip)
        return result
        
    except Exception as e:
        return error_response(f"手机登录失败: {str(e)}")


@router.get("/info")
async def get_user_info(request: Request):
    """获取用户信息 - 从token中获取用户ID"""
    try:
        # 从请求头获取token
        auth_header = request.headers.get('Authorization')
        if not auth_header or not auth_header.startswith('Bearer '):
            return error_response("未提供有效的认证令牌", 401)
        
        token = auth_header.split(' ')[1]
        user_id = get_user_id_from_token(token)
        
        if not user_id:
            return error_response("无效的认证令牌", 401)
        
        logger.info(f"从token获取用户ID: {user_id}")
        
        # 获取用户信息
        result = user_service.get_user_info(user_id)
        return result
        
    except JWTError:
        return error_response("无效的认证令牌", 401)
    except Exception as e:
        logger.error(f"获取用户信息失败: {str(e)}")
        return error_response(f"获取用户信息失败: {str(e)}")


@router.put("/info")
async def update_user_info(request: Request, update_data: Dict[str, Any]):
    """更新用户信息 - 从token中获取用户ID"""
    try:
        # 从请求头获取token
        auth_header = request.headers.get('Authorization')
        if not auth_header or not auth_header.startswith('Bearer '):
            return error_response("未提供有效的认证令牌", 401)
        
        token = auth_header.split(' ')[1]
        user_id = get_user_id_from_token(token)
        
        if not user_id:
            return error_response("无效的认证令牌", 401)
        
        logger.info(f"更新用户信息: user_id={user_id}, data={update_data}")
        
        # 更新用户信息
        result = user_service.update_user_info(user_id, update_data)
        return result
        
    except JWTError:
        return error_response("无效的认证令牌", 401)
    except Exception as e:
        logger.error(f"更新用户信息失败: {str(e)}")
        return error_response(f"更新用户信息失败: {str(e)}")


@router.get("/cart/list")
async def get_cart_list(request: Request):
    """获取购物车列表"""
    try:
        # 获取当前用户
        current_user = get_current_user(request)
        if not current_user:
            return error_response("用户未登录", 401)
        
        # 这里应该调用购物车服务
        # 暂时返回空列表
        return success_response([], "获取购物车列表成功")
        
    except Exception as e:
        return error_response(f"获取购物车列表失败: {str(e)}")